define(["jquery"], function ($) {
    let js = document.scripts;
    let path;
    for (let i = 0; i < js.length - 1; i++) {
        if (js[i].src.indexOf('ivs') > 0) {
            path = js[i].src.substring(0, js[i].src.lastIndexOf("/"));
        }
    }

    class Ivs {
        url = 'http://120.79.137.194:52467/openApi';
        jssesionId = '';
        layer = layui.layer;
        tree = layui.tree;
        is_debug = false;
        deviceList = [];
        channelList = [];
        treeList = [];
        filePath = path;
        playerList;
        playerContainer = $('[data-player-container]');
        playerToolbars = $('[data-player-toolbars]');
        splitButton;
        selectSplit = 1;
        allScreen = 1;
        currentScreen = 0;
        _nextScreen = 0;

        constructor(debug = false) {
            this.splitButton = [1, 2, 6, 9, 12, 16];
            this.playerList = [];
            this.is_debug = debug;
            let that = this;
            $(document).on('click', '[data-player-toolbars]>button', function (e) {
                e.preventDefault();
                let num = Number($(this).attr('data-split-screen'));
                that.renderPlayer(num);
                that.allScreen = num;
                $(this).addClass('layui-btn-active').siblings().removeClass('layui-btn-active');
            });
            $(document).on('click', 'i.layui-icon-voice', async function (e) {
                e.preventDefault();
                let num = Number($(this).attr('data-player-idx'));
                let nmsName = that.playerList[num].nmsName;
                if(!nmsName){
                    return;
                }
                try {
                    let {data: {error: {errorcode}, url, urlIn, talkId}} = await that.startVoiceCall(nmsName);
                    errorcode = Number(errorcode);
                    if (errorcode === 0) {
                        that.initTalkMic(talkId, nmsName, num);
                        that.initTalkSpeaker(talkId,nmsName,num);
                        setTimeout(() =>{
                            let talkMic = that.playerList[num].talkMic[0];
                            let pos = urlIn.lastIndexOf('/');
                            let live = urlIn.substring(0, pos);
                            let name = urlIn.substring(pos + 1);
                            talkMic.publish(live, name);

                            let talkSpeaker = that.playerList[num].talkSpeaker[0];
                            talkSpeaker.setMediaResourceURL(url);
                            talkSpeaker.setAutoPlay(true);
                        }, 500);
                    } else if (errorcode === 7) {
                        return that.msg('设备占线，请稍候再试！');
                    } else {
                        console.log('出现错误');
                    }
                }catch (e) {}
            });
            $(document).on('click', 'i.layui-icon-pause', async function (e) {
                e.preventDefault();
                let num = Number($(this).attr('data-player-idx'));
                let nmsName = that.playerList[num].nmsName;
                if(!nmsName){
                    return;
                }
                let talkMic = that.playerList[num].talkMic[0];
                let talkSpeaker = that.playerList[num].talkSpeaker[0];
                let talkId = $(talkMic).attr('talkId');
                try {
                    let {code, msg} = await that.stopVoiceCall(talkId, nmsName);
                    if(talkMic!=null){
                        talkMic.disconnect();
                    }
                    if(code === 200){
                        talkSpeaker.stop2();
                        talkSpeaker.setMediaResourceURL("");
                        talkSpeaker.setAutoPlay(false);
                    }else{
                        console.info(msg);
                    }
                }catch (e) {}
            });
            $(document).on('click', 'i.layui-icon-close-fill', async function (e) {
                e.preventDefault();
                let num = Number($(this).attr('data-player-idx'));
                let _player = that.playerList[num];
                if(!_player.nmsName){
                    return;
                }
                await that.stopDeviceLive(_player.nmsName,_player.videoId);
                that.clearPlayer(num);
            });

            console.log('欢迎使用ivs，create by jswei.');
        }

        debug(debug = false) {
            this.is_debug = debug;
            return this;
        }

        success(msg) {
            this.layer.msg(msg, {
                icon: 1,
                scrollbar: false,
                time: 2000,
                shadeClose: true
            });
            return this;
        }

        alert(msg) {
            this.layer.alert(msg, {scrollbar: false});
            return this;
        }

        error(msg) {
            this.layer.msg(msg, {
                icon: 2,
                scrollbar: false,
                time: 3000,
                shadeClose: true
            });
            return this;
        }

        tips(msg, time) {
            this.layer.msg(msg, {
                time: (time || 3) * 1000,
                shadeClose: true
            });
            return this;
        }

        /**
         * 请求接口
         * @param url 请求地址
         * @param data 请求数据
         * @param method 请求方法
         * @param out 外部链接
         * @returns {Promise<any>}
         */
        require(url = '', data = null, method = 'post', out = false) {
            return new Promise((resolve, reject) => {
                let headers = {};
                let jssesionId = this.jssesionId || '';
                if (url.indexOf('login') < 0 && !jssesionId) {
                    return reject('错误的请求:[jssesionId] is null');
                } else if (url.indexOf('login') < 0 && jssesionId) {
                    headers.jssesionId = jssesionId;
                }
                let _url = url;
                if (!out) {
                    data = data ? JSON.stringify(data) : {};
                    _url = `${this.url}${url}`;
                    $.ajax({
                        url: _url,
                        type: method,
                        dateType: 'json',
                        cache: false,
                        contentType: 'application/json',
                        headers: headers,
                        data: data,
                        success: (data) => {
                            if (this.is_debug) {
                                console.log('请求成功，获取的数据是： %s.', JSON.stringify(data));
                            }
                            resolve(data);
                        },
                        error: (data) => {
                            reject(data);
                        }
                    });
                } else {
                    $.ajax({
                        type: method,
                        url: _url,
                        data: data,
                        dataType: "jsonp",
                        jsonpCallback: "success_jsonpCallback",
                        success: (data) => {
                            resolve(data);
                        },
                        error: (data) => {
                            reject(data);
                        }
                    });
                }
                if (this.is_debug) {
                    console.log('请求的代理地址是：%s,headers为：%s,请求的用到的参数为: %s.', _url, JSON.stringify(headers), data);
                }
            });
        }

        login(account = '', pwd = '') {
            return this.require('/login.dcw', {account, pwd});
        }

        logout() {
            this.require('/logout.dcw');
            return this;
        }

        getTreeData(data = null) {
            let _list = data || this.deviceList;
            _list.map(item => {
                this.treeList.push({
                    title: `${item.nmsAlias}(${item.onLine ? '在线' : '离线'})`,
                    id: item.termSn,
                    ...item
                });
            });
            return this;
        }

        clearDevice() {
            this.deviceList = [];
            return this;
        }

        clearTree() {
            this.treeList = [];
            this.getTreeData();
            return this;
        }

        clearPlayer(_idx){
            $(`.gps${_idx}`).html('').hide();
            $(`.channel${_idx}`).html('');
            $(`#moviePlayerWapper_${_idx}`).attr('videoId', '')
                .attr('nmsName', '')
                .attr('channelId', '')
                .attr('streamType', '');
            $(`#voiceTalkOut_${_idx}`).remove();
            $(`#voiceTalkIn_${_idx}`). remove();
            this.playerList[_idx].videoId = '';
            this.playerList[_idx].nmsName = '';
            this.playerList[_idx].channelId = '';
            this.playerList[_idx].streamType = '';
            this.playerList[_idx].videoId = '';
            this.playerList[_idx].used = false;
            return this;
        }

        clearAll() {
            this.clearDevice();
            this.clearTree();
            return this;
        }

        renderTree() {
            let that = this;
            this.tree.render({
                elem: '#deviceList',
                data: this.treeList,
                async click({data, state, elem}) {
                    let _idx = that.currentScreen;
                    let streamType = 1;
                    let channelId = 1;
                    let nmsName = data.nmsName
                    // if(that._nextScreen > that.allScreen){
                    //     console.info('已到最多屏');
                    //     return;
                    // }
                    if (that._nextScreen) {
                        _idx = that._nextScreen;
                    }
                    let _currentPlayer = that.playerList[_idx];
                    this.channelList = data.channelList;
                    this.is_debug ? console.log('已选中机位【%s】，信道有：%s', data.title, JSON.stringify(this.channelList)) : '';
                    let {code, data: live, msg} = await that.startDeviceLive(nmsName, channelId, _currentPlayer.uuid, streamType);
                    if (Number(code) !== 200) {
                        return that.error(msg);
                    }
                    let {svr, videoId} = live;
                    let html = '通道：<select name="channel">';
                    this.channelList.map(item => {
                        html += `<option value="${JSON.stringify(item)}">${item.name}</option>`;
                    });
                    html += '</select>';
                    let {data: {latitude, longitude, time, speed, vin, vid}} = await that.getDeviceLocationInfo(data.nmsName);
                    let {result: {formatted_address, sematic_description}} = await that.getGpsAddress(`${latitude},${longitude}`, `${longitude},${latitude}`);
                    let gps = `<ul>
                        <li>设备：<span class="driver">${vin}${vid ? '(' + vid + ')' : ''}</span></li>
                        <li>坐标：<span class="lng">${longitude}</span>,<span class="lat">${latitude}</span></li>
                        <li>速度：<span class="speed">${speed}km/h</span></li>
                        <li>时间：<span class="time">${time}</span></li>
                        <li>地址：<span class="address">${formatted_address}&nbsp;${sematic_description}</span></li>
                    </ul>`;
                    _currentPlayer.used = true;
                    $(`.gps${_idx}`).html(gps).show();
                    $(`.channel${_idx}`).html(html);
                    $(`#moviePlayerWapper_${_idx}`).attr('videoId', videoId);
                    $(`#moviePlayerWapper_${_idx}`).attr('nmsName', nmsName);
                    $(`#moviePlayerWapper_${_idx}`).attr('channelId', channelId);
                    $(`#moviePlayerWapper_${_idx}`).attr('streamType', streamType);
                    _currentPlayer.videoId = videoId;
                    _currentPlayer.nmsName = nmsName;
                    _currentPlayer.channelId = channelId;
                    _currentPlayer.streamType = streamType;
                    if (that.allScreen > 1 && that._nextScreen < that.allScreen) {
                        that._nextScreen = that.currentScreen + 1;
                    }
                    setTimeout(() => {
                        let player = $(`#moviePlayerWapper_${_idx}`)[0];
                        player.setMediaResourceURL(svr.url);
                        player.setAutoPlay(true);
                    }, 500);
                }
            });
        }

        /**
         * 获取定位位置
         *
         * @param location
         * @param coords
         * @param coordtype
         * @param output
         * @param extensions_road
         * @param extensions_poi
         * @param ak
         * @returns {Promise<any>}
         */
        async getGpsAddress(location, coords, coordtype = 'wgs84ll', output = 'json', extensions_road = 'true', extensions_poi = 1, ak = 'xooZZG25yNjbmCFGytrRyor0') {
            return this.require('https://api.map.baidu.com/reverse_geocoding/v3/', {
                location,
                ak,
                output,
                coordtype,
                extensions_road,
                extensions_poi
            }, 'get', true);
        }

        /**
         * 渲染播放器
         * @param len 个数
         * @param width 宽
         * @param height 高
         */
        renderPlayer(len = 0, width = 0, height = 420) {
            let col;
            len = len ? len : this.selectSplit;
            if (len === 1) {
                col = 12;
            } else if (len === 2) {
                col = 6;
                height = height / 1.5;
            } else if (len > 2 && len <= 9) {
                col = 4;
                height = height / 2;
            } else {
                col = 3;
                height = height / 3.2;
            }
            this.playerList = [];
            let html = `<div class="layui-row layui-col-space5">`;
            for (let i = 0; i < len; i++) {
                html += `<div class="layui-col-xs${col} layui-col-sm${col} layui-col-md${col} channel-player-container">
                            <div class="channel-player-info">
                                <div class="channel-list channel${i}">
                                </div>
                                <div class="gps-info gps${i}"></div>
                                <div class="player-mic">
                                    <i class="layui-icon layui-icon-voice" title="点击开始对讲" data-player-idx="${i}"></i>
                                    <i class="layui-icon layui-icon-pause" title="点击停止对讲" data-player-idx="${i}"></i>
                                </div>
                                <i class="layui-icon layui-icon-close-fill" title="点击关闭视频" data-player-idx="${i}"></i>
                            </div>
                            <object type="application/x-shockwave-flash" name="player" id="moviePlayerWapper_${i}"
                                    videoId="" nmsName="" channelId="" streamType=""
                                    style="color: #EFEFEF;"
                                    width="${width ? width : '100%'}" height="${height ? height : '100%'}"
                                    data="${this.filePath}/rtmp_player/StrobeMediaPlayback.swf">
                                <param name="allowFullScreen" value="true">
                                <param name="wmode" value="transparent">
                                <param name="allowScriptAccess" value="always">
                                <param name="bgcolor" value="#000000">
                                <param name="menu" value="false">
                                <param name="ScaleMode" value="stretch">
                                <param name="flashvars" value="playButtonOverlay=false&controlBarMode=none&autoPlay=false&src=rtmp:localhost/live&volume=0&javascriptCallbackFunction=onVideoFlashCreated">
                            </object>
                        </div>`;

                this.playerList[i] = {
                    name: `moviePlayerWapper_${i}`,
                    node: $(`#moviePlayerWapper_${i}`),
                    key: i,
                    used: false,
                    uuid: (new Date().getTime() + "").substring(6) + Math.ceil((Math.random()) * 100)
                };
            }
            html += `</div>`;
            this.playerContainer.html(html);
            this.is_debug ? console.log('初始化%s个屏幕，播放器列表：%s', data.title, JSON.stringify(this.playerList)) : '';
        }

        /**
         * 初始化分屏按钮
         */
        renderSplitButton() {
            let html = '';
            this.splitButton.map(item => {
                if (item === this.selectSplit) {
                    html += `<button type="button" data-split-screen="${item}" class="layui-btn layui-btn-active">${item}分屏</button>`;
                } else {
                    html += `<button type="button" data-split-screen="${item}" class="layui-btn">${item}分屏</button>`;
                }
            });
            this.playerToolbars.html(html);
            this.renderPlayer();
        }

        /**
         * 初始化对讲听筒插件
         * @param talkId
         * @param termSn
         */
        initTalkSpeaker(talkId = '', termSn = '', idx = '') {
            let AudioSpeakerFlashStr = '<object type="application/x-shockwave-flash" ' +
                'name="voiceTalkOut" talkId="' + talkId + '" termSn="' + termSn + '" ' +
                'data="' + this.filePath + '/rtmp_player/StrobeMediaPlayback.swf" id="voiceTalkOut_' + idx + '" style="visibility:visible;width: 0;height: 0;">' +
                '<param name="allowFullScreen" value="false">' +
                '<param name="allowScriptAccess" value="always">' +
                '<param name="bgcolor" value="#ffffff">' +
                '<param name="menu" value="false">' +
                '<param name="flashvars" value="javascriptCallbackFunction=onAudioplayerCreated&controlBarMode=none&autoPlay=true&volume=9">' +
                '</object>';
            $(`#moviePlayerWapper_${idx}`).after(AudioSpeakerFlashStr);
            this.playerList[idx].talkSpeaker = $(`#voiceTalkOut_${idx}`);
        }

        /**
         * 初始化对讲麦克风插件
         * @param talkId
         * @param termSn
         * @param idx
         */
        initTalkMic(talkId = '', termSn = '', idx = '') {
            let AudioMicFlashStr = '<object type="application/x-shockwave-flash" ' +
                'name="voiceTalkIn" talkId="' + talkId + '" termSn="' + termSn + '" ' +
                'data="' + this.filePath + '/rtmp_player/dcwIvs_Mic.swf" width="220" height="140" id="voiceTalkIn_' + idx + '" style="visibility:visible;">' +
                '<param name="allowFullScreen" value="false">' +
                '<param name="allowScriptAccess" value="always">' +
                '<param name="bgcolor" value="#ffffff">' +
                '<param name="wmode" value="transparent">' +
                '<param name="flashvars" value="javascriptCallbackFunction=onAudioplayerCreated&controlBarMode=none&autoPlay=true&volume=9">' +
                '</object>';
            $(`#moviePlayerWapper_${idx}`).after(AudioMicFlashStr);
            this.playerList[idx].talkMic = $(`#voiceTalkIn_${idx}`);
        }

        /**
         * 获取设备列表
         * @returns {Promise<any>}
         */
        getDeviceList() {
            return new Promise(async (resolve, reject) => {
                this.deviceList = [];
                let {code, msg, data} = await this.require('/getDeviceInfoList.dcw');
                if (Number(code) !== 200) {
                    reject(msg);
                    return this.alert(msg);
                }
                this.deviceList = data;
                this.getTreeData().renderTree();
                resolve({code, msg, data});
            });
        }

        /**
         * 实时视频
         * @param nmsName 设备编号
         * @param channelId 视频通道编号,视频会话ID（用于关闭视频）（必填）可以使用时间戳
         * @param videoId 视频会话id
         * @param streamType 码流类型 1：子码流 0：主码流
         * @returns {Promise<any>}
         */
        startDeviceLive(nmsName, channelId, videoId, streamType = 1) {
            return this.require('/videoMoni.dcw', {
                nmsName,
                channelId,
                videoId,
                streamType
            });
        }

        /**
         * 结束直播
         * @param nmsName 设备编号
         * @param videoId 视频会话id
         * @returns {Promise<any>}
         */
        stopDeviceLive(nmsName, videoId) {
            return this.require('/videoStop.dcw', {
                videoId,
                nmsName
            });
        }

        /**
         * 开始对话
         * @param nmsName 设备编号
         * @param channelId 对讲通道编号,对讲固定为33
         * @returns {Promise<*>}
         */
        startVoiceCall(nmsName, channelId = 33) {
            return this.require('/voiceCalls.dcw', {
                nmsName,
                channelId
            });
        }

        /**
         * 挂断对话
         *
         * @param talkId
         * @param nmsName
         * @param channelId
         * @returns {Promise<*>}
         */
        stopVoiceCall(talkId, nmsName, channelId = 33) {
            return this.require('/stopVoiceCalls.dcw', {
                nmsName,
                channelId,
                talkId
            });
        }


        /**
         * 获取单个设备信息
         * @param vin 设备编号（必填）
         * @returns {Promise<any>}
         */
        getDeviceInfo(vin) {
            return this.require('/deviceInfoByVin.dcw', {
                vin
            });
        }

        /**
         * 获取设备地位
         * @param nmsName
         * @returns {Promise<any>}
         */
        getDeviceLocationInfo(nmsName) {
            return this.require('/getDeviceGPStatus.dcw', {
                nmsName
            });
        }

        /**
         * 获取设备在线状态
         * @param nmsName 设备编号（必填）
         * @returns {Promise<any>}
         */
        getDeviceOnlineInfo(nmsName) {
            return this.require('/deviceInfoByTermSn.dcw', {
                nmsName
            });
        }
    }

    return Ivs;
});
